home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * normal.c
- *
- * This module implements solid texturing functions that perturb the surface
- * normal to create a bumpy effect.
- *
- * from Persistence of Vision Raytracer
- * Copyright 1993 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- /*
- Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
- "An Image Synthesizer" By Ken Perlin.
- Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley)
- */
-
- #include "frame.h"
- #include "vector.h"
- #include "povproto.h"
- #include "texture.h"
-
- extern unsigned short crctab[256];
-
- void ripples (x, y, z, Tnormal, normal)
- DBL x, y, z;
- TNORMAL *Tnormal;
- VECTOR *normal;
- {
- register int i;
- VECTOR point;
- register DBL length, scalar, index;
-
- if (Options & DEBUGGING)
- printf ("ripples %g %g %g", x, y, z);
-
- for (i = 0 ; i < NUMBER_OF_WAVES ; i++)
- {
- point.x = x;
- point.y = y;
- point.z = z;
- VSub (point, point, Wave_Sources[i]);
- VDot (length, point, point);
- if (length == 0.0)
- length = 1.0;
-
- length = sqrt(length);
- index = length*Tnormal->Frequency
- + Tnormal -> Phase;
- scalar = cycloidal (index) * Tnormal -> Amount;
-
- if (Options & DEBUGGING)
- printf (" index %g scalar %g length %g\n", index, scalar, length);
-
- VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
- VAdd (*normal, *normal, point);
- }
- VNormalize (*normal, *normal);
- }
-
- void waves (x, y, z, Tnormal, normal)
- DBL x, y, z;
- TNORMAL *Tnormal;
- VECTOR *normal;
- {
- register int i;
- VECTOR point;
- register DBL length, scalar, index, sinValue ;
-
- if (Options & DEBUGGING)
- printf ("waves %g %g %g\n", x, y, z);
-
- for (i = 0 ; i < NUMBER_OF_WAVES ; i++)
- {
- point.x = x;
- point.y = y;
- point.z = z;
- VSub (point, point, Wave_Sources[i]);
- VDot (length, point, point);
- if (length == 0.0)
- length = 1.0;
-
- length = sqrt(length);
- index = (length * Tnormal -> Frequency * frequency[i])
- + Tnormal -> Phase;
- sinValue = cycloidal (index);
-
- scalar = sinValue * Tnormal -> Amount /
- frequency[i];
- VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
- VAdd (*normal, *normal, point);
- }
- VNormalize (*normal, *normal);
- }
-
-
- void bumps (x, y, z, Tnormal, normal)
- DBL x, y, z;
- TNORMAL *Tnormal;
- VECTOR *normal;
- {
- VECTOR bump_turb;
-
- if (Tnormal -> Amount == 0.0)
- return; /* why are we here?? */
-
- if (Options & DEBUGGING)
- printf ("bumps %g %g %g\n", x, y, z);
-
- DNoise (&bump_turb, x, y, z); /* Get Normal Displacement Val. */
- VScale(bump_turb, bump_turb, Tnormal->Amount);
- VAdd (*normal, *normal, bump_turb); /* displace "normal" */
- VNormalize (*normal, *normal); /* normalize normal! */
- return;
- }
-
- /*
- dents is similar to bumps, but uses noise() to control the amount of
- dnoise() perturbation of the object normal...
- */
-
- void dents (x, y, z, Tnormal, normal)
- DBL x, y, z;
- TNORMAL *Tnormal;
- VECTOR *normal;
- {
- VECTOR stucco_turb;
- DBL noise;
-
- if (Tnormal -> Amount == 0.0)
- return; /* why are we here?? */
-
- noise = Noise (x, y, z);
-
- noise = noise * noise * noise * Tnormal->Amount;
-
- if (Options & DEBUGGING)
- printf ("dents %g %g %g noise %g\n", x, y, z, noise);
-
- DNoise (&stucco_turb, x, y, z); /* Get Normal Displacement Val. */
-
- VScale (stucco_turb, stucco_turb, noise);
- VAdd (*normal, *normal, stucco_turb); /* displace "normal" */
- VNormalize (*normal, *normal); /* normalize normal! */
- return;
- }
-
-
-
-
- /*
- Ideas garnered from the April 89 Byte Graphics Supplement on RenderMan,
- refined from "The RenderMan Companion, by Steve Upstill of Pixar, (C) 1990
- Addison-Wesley.
- */
-
-
- /*
- wrinkles - This is my implementation of the dented() routine, using
- a surface iterative fractal derived from DTurbulence. This is a 3-D vers.
- (thanks to DNoise()...) of the usual version using the singular Noise()...
- Seems to look a lot like wrinkles, however... (hmmm)
- */
-
- void wrinkles (x, y, z, Tnormal, normal)
- DBL x, y, z;
- TNORMAL *Tnormal;
- VECTOR *normal;
- {
- register int i;
- register DBL scale = 1.0;
- VECTOR result, value;
-
- if (Tnormal -> Amount == 0.0)
- return; /* why are we here?? */
-
- if (Options & DEBUGGING)
- printf ("wrinkles %g %g %g\n", x, y, z);
-
- result.x = 0.0;
- result.y = 0.0;
- result.z = 0.0;
-
- for (i = 0; i < 10 ; scale *= 2.0, i++)
- {
- DNoise(&value, x * scale, y * scale, z * scale); /* * scale,*/
- result.x += FABS (value.x / scale);
- result.y += FABS (value.y / scale);
- result.z += FABS (value.z / scale);
- }
-
- VScale(result, result, Tnormal->Amount);
- VAdd (*normal, *normal, result); /* displace "normal" */
- VNormalize (*normal, *normal); /* normalize normal! */
- return;
- }
-
- TNORMAL *Create_Tnormal ()
- {
- TNORMAL *New;
-
- if ((New = (TNORMAL *) malloc (sizeof (TNORMAL))) == NULL)
- MAError ("normal");
-
- INIT_TPATTERN_FIELDS(New,NO_NORMAL);
- New->Amount = 0.0;
- return (New);
- }
-
- TNORMAL *Copy_Tnormal (Old)
- TNORMAL *Old;
- {
- TNORMAL *New;
-
- if (Old != NULL)
- {
- New = Create_Tnormal ();
- *New = *Old;
-
- New->Image = Copy_Image (Old->Image);
- New->Trans = Copy_Transform (Old->Trans);
- }
- else
- New = NULL;
-
- return (New);
- }
-
- void Translate_Tnormal(Tnormal,Vector)
- TNORMAL *Tnormal;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- if (Tnormal == NULL)
- return;
-
- Compute_Translation_Transform (&Trans, Vector);
- Transform_Tnormal (Tnormal, &Trans);
- }
-
- void Rotate_Tnormal(Tnormal,Vector)
- TNORMAL *Tnormal;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- if (Tnormal == NULL)
- return;
-
- Compute_Rotation_Transform (&Trans, Vector);
- Transform_Tnormal (Tnormal, &Trans);
- }
-
- void Scale_Tnormal(Tnormal,Vector)
- TNORMAL *Tnormal;
- VECTOR *Vector;
- {
- TRANSFORM Trans;
-
- if (Tnormal == NULL)
- return;
-
- Compute_Scaling_Transform (&Trans, Vector);
- Transform_Tnormal (Tnormal, &Trans);
- }
-
- void Transform_Tnormal(Tnormal,Trans)
- TNORMAL *Tnormal;
- TRANSFORM *Trans;
- {
- if (Tnormal == NULL)
- return;
-
- if (!Tnormal->Trans)
- Tnormal->Trans = Create_Transform ();
-
- Compose_Transforms (Tnormal->Trans, Trans);
- }
-
- void Destroy_Tnormal(Tnormal)
- TNORMAL *Tnormal;
- {
- if (Tnormal == NULL)
- return;
-
- Destroy_Image (Tnormal->Image);
- Destroy_Transform (Tnormal->Trans);
- free (Tnormal);
- }
-
- void Post_Tnormal (Tnormal)
- TNORMAL *Tnormal;
- {
- if (Tnormal == NULL)
- return;
-
- if (Tnormal->Type == NO_NORMAL)
- Error("No normal type given");
-
- Tnormal->Flags |= POST_DONE;
-
- return;
- }
-